package ImportNewNioStudy;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;

/**
 * Created by gzhd on 2017/11/28.
 */
public class ImServerConnect {

    private static final int BUF_SIZE = 1024;
    private static final int PORT     = 8080;
    private static final int TIMEOUT  = 3000;

    public static void main(String[] args) {
        InitServer();
    }

    public static void handleAccept(SelectionKey key) throws IOException {
        ServerSocketChannel ssChannel = (ServerSocketChannel) key.channel();
        SocketChannel sc        = ssChannel.accept();
        sc.configureBlocking(false);
        sc.register(key.selector(), SelectionKey.OP_READ, ByteBuffer.allocateDirect(BUF_SIZE));
    }


    
    public static void handleRead(SelectionKey key) throws IOException {
        SocketChannel sc        = (SocketChannel) key.channel();
        ByteBuffer    buf       = (ByteBuffer) key.attachment();
        long          bytesRead = sc.read(buf);
        while (bytesRead > 0) {
            buf.flip();
            while (buf.hasRemaining()) {
                System.out.print((char) buf.get());
            }
            System.out.println();
            buf.clear();
            bytesRead = sc.read(buf);
        }
        if (bytesRead == -1) {
            sc.close();
        }
    }



    private  static void read(SelectionKey key)  throws Exception{
        SocketChannel channel = (SocketChannel) key.channel();
        ByteBuffer buffer = ByteBuffer.allocate(100);
        channel.read(buffer);
        byte[] data = buffer.array();
        String msg=new String(data).trim();
        System.out.println("服务端收到信息:"+msg);
        ByteBuffer outbuffer = ByteBuffer.wrap(msg.getBytes());
        channel.write(outbuffer);

    }

    public static void handleWrite(SelectionKey key) throws IOException {
        ByteBuffer buf = (ByteBuffer) key.attachment();
        buf.flip();
        SocketChannel sc = (SocketChannel) key.channel();
        while (buf.hasRemaining()) {
            sc.write(buf);
        }
        buf.compact();
    }

    public static void InitServer() {
        Selector selector = null;
        ServerSocketChannel ssc      = null;
        try {
            selector = Selector.open();
            ssc = ServerSocketChannel.open();
            ssc.socket()
                    .bind(new InetSocketAddress(PORT));
            ssc.configureBlocking(false);
            ssc.register(selector, SelectionKey.OP_ACCEPT);
            System.out.println("服务器启动成功！");
            while (true) {
                if (selector.select(TIMEOUT) == 0) {
                    System.out.println("没有收到任何响应··再等");
                    continue;
                }
                Iterator<SelectionKey> iter = selector.selectedKeys()
                        .iterator();
                while (iter.hasNext()) {
                    SelectionKey key = iter.next();
//					改过的在这里
                    iter.remove();
                    if (key.isAcceptable()) {
                        System.out.println("isAcceptable事件");
                        handleAccept(key);
                    }
                    if (key.isReadable()) {
                        System.out.println("isReadable事件");
//						handleRead(key);
                        read(key);
                    }
                    if (key.isWritable() && key.isValid()) {
                        System.out.println("isWritable事件");
                        handleWrite(key);
                    }
                    if (key.isConnectable()) {
                        System.out.println("isConnectable = true  连接成功！");
                    }
//					原来的是在这里
//					iter.remove();

                }
            }

        }
        catch (IOException e) {
            e.printStackTrace();
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        finally {
            try {
                if (selector != null) {
                    selector.close();
                }
                if (ssc != null) {
                    ssc.close();
                }
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

}
